package com.freesky.quartz.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freesky.biz.activity.domain.TStockMch;
import com.freesky.biz.activity.domain.TStockMonitor;
import com.freesky.biz.activity.mapper.StockMonitorMapper;
import com.freesky.biz.activity.service.IWebhookService;
import com.freesky.biz.pay.config.WxPayConfiguration;
import com.freesky.common.core.redis.RedisCache;
import com.freesky.common.utils.DateUtils;
import com.freesky.common.utils.StringUtils;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.mchange.v1.identicator.IdList;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.URI;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 微信券的监控：
 * stock_type:NORMAL、DISCOUNT_CUT
 *
 * NORMAL:根据总券数(totalCount)和已发券数(grantCount)
 *
 */
@Slf4j
@Component("stockMonitorTask")
public class StockMonitorTask {
    private static final Logger logger = LoggerFactory.getLogger(StockMonitorTask.class);

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IWebhookService webhookService;

    @Autowired
    private StockMonitorMapper stockMonitorMapper;

    @Autowired
    private WxPayService payService;

    @Autowired
    private WxPayConfiguration wxPayConfiguration;

    private static final long INTERVAL = 60 * 1000 * 60;       //每隔1小时查询一次性
    private long lastAlarmTime = 0;

    //紫虫子
    private WxPayService payService66;
    //标点
    private WxPayService payServiceBiao;
    private String STOCK_MONITOR_KEY = "STOCK:MONITOR:LAST";
    private String STOCK_MONITOR_AlARM_KEY = "STOCK:MONITOR:";
    private final String STOCK_CREATOR_MCHID = "1615748766";

    private final String STOCK_CREATOR_MCHID_BIAO = "1682380270";
    @PostConstruct
    public void stockMonitorInit(){
        try {
            payService66 = new WxPayServiceImpl();
            WxPayConfig wxPayConfig = wxPayConfiguration.getPayConfigs(STOCK_CREATOR_MCHID);
            payService66.setConfig(wxPayConfig);

            //标点网络
            payServiceBiao = new WxPayServiceImpl();
            WxPayConfig wxPayConfig2 = wxPayConfiguration.getPayConfigs(STOCK_CREATOR_MCHID_BIAO);
            payServiceBiao.setConfig(wxPayConfig2);

        } catch (Exception ioe){
            ioe.printStackTrace();
        }
    }

    public void taskProcess() {
        //微信立减金
        couponMonitor();

        //每个一个小时获取所有微信的券
        if(canAllow()) {
            loadMchCouponList();
        }
    }

    /**
     * 微信立减金监控
     */
    public void couponMonitor(){
        List<TStockMonitor> alarmStockList = new ArrayList<>();

        List<TStockMonitor> stockMonitorModelList = stockMonitorMapper.findStockMonitorList();
        for(TStockMonitor stockMonitor:stockMonitorModelList){
            try{
                //是否已告警过
                String result = "";
                if(STOCK_CREATOR_MCHID.equalsIgnoreCase(stockMonitor.getMchId())) {
                    result = this.payService66.getV3(payService66.getPayBaseUrl()+"/v3/marketing/favor/stocks/"+stockMonitor.getId()+"?stock_creator_mchid="+stockMonitor.getMchId());
                } else if(STOCK_CREATOR_MCHID_BIAO.equalsIgnoreCase(stockMonitor.getMchId())) {
                    result = this.payServiceBiao.getV3(payServiceBiao.getPayBaseUrl()+"/v3/marketing/favor/stocks/"+stockMonitor.getId()+"?stock_creator_mchid="+stockMonitor.getMchId());
                } else {
                    result = this.payService.getV3(payService.getPayBaseUrl()+"/v3/marketing/favor/stocks/"+stockMonitor.getId()+"?stock_creator_mchid="+stockMonitor.getMchId());
                }

                JSONObject jsonObject = JSON.parseObject(result);
                String beginTime = DateUtils.formatDateTime(DateUtils.dealDateFormat(jsonObject.getString("available_begin_time")));
                String endTime = DateUtils.formatDateTime(DateUtils.dealDateFormat(jsonObject.getString("available_end_time")));
                stockMonitor.setBeginTime(beginTime);
                stockMonitor.setEndTime(endTime);

                stockMonitor.setStockName(jsonObject.getString("stock_name"));
                if(jsonObject.containsKey("stock_use_rule")) {
                    JSONObject jsonStockUseRule = jsonObject.getJSONObject("stock_use_rule");
                    stockMonitor.setTotalCount(jsonStockUseRule.getString("max_coupons"));
                    stockMonitor.setMaxAmount(jsonStockUseRule.getString("max_amount"));
                    stockMonitor.setMaxAmountByDay(jsonStockUseRule.getString("max_amount_by_day"));
                    stockMonitor.setMaxCouponsPerUser(jsonStockUseRule.getString("max_coupons_per_user"));
                }

                //https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/15394677
                stockMonitor.setGrantCount(jsonObject.getString("distributed_coupons"));
                stockMonitor.setStatus(jsonObject.getString("status"));
                stockMonitorMapper.updateStockMonitorById(stockMonitor);

                if(alarmStockList.size()<8){
                    boolean hasAlaramFlag = alarmStock(stockMonitor);
                    if(hasAlaramFlag){
                        alarmStockList.add(stockMonitor);
                    }
                }

            } catch (Exception ioe){
                ioe.printStackTrace();
            }
        }

        //发送告警通知
        List<Map<String,String>> alarmMapList = new ArrayList<>();
        if(alarmStockList.size()>0){
            final String WEB_HOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=23315a40-d096-4758-b766-c2cecc661e5d";
            int nLoop = 0;
            for(TStockMonitor stockMonitor : alarmStockList){
                Map<String,String> stockMap = new HashMap<>();
                long lnLeftCount = Long.parseLong(stockMonitor.getTotalCount()) - Long.parseLong(stockMonitor.getGrantCount());

                if(lnLeftCount<= Long.parseLong(stockMonitor.getAlarmCount())){
                    stockMap.put("title","*"+stockMonitor.getMchName() +":"+stockMonitor.getId()+"," + stockMonitor.getStockName()+",余："+lnLeftCount);
                } else {
                    stockMap.put("title",stockMonitor.getMchName() +":"+stockMonitor.getId()+"," + stockMonitor.getStockName()+","+stockMonitor.getEndTime());
                }

                String description = stockMonitor.getMchName();
                //String description = stockMonitor.getMchName()+",【总券数："+stockMonitor.getTotalCount()+"】【余券："+lnLeftCount+"】【有效期至："+stockMonitor.getEndTime()+"】";
                stockMap.put("description",description);
                stockMap.put("url","https://pay.weixin.qq.com/xdc/mktbatchdetails/index.php/extend/mktaccount/getstockdetail?type=2&stockid="+stockMonitor.getId()+"&index=1");
                //stockMap.put("picurl","");
                alarmMapList.add(stockMap);
                redisCache.setCacheObject(STOCK_MONITOR_AlARM_KEY + stockMonitor.getId(),"1",60, TimeUnit.MINUTES);

                nLoop = nLoop + 1;
            }

            if(alarmMapList.size()>0) {
                int nHours = Integer.parseInt(DateUtil.format(new Date(),"HH"));
                if(nHours<8 || nHours>21){
                    return;
                }
                webhookService.sendNews(WEB_HOOK_URL, alarmMapList);
            }
        }
        logger.info("【StockMonitorJob】数据处理完成!");
    }

    public boolean alarmStock(TStockMonitor stockMonitor){
        if("0".equalsIgnoreCase(stockMonitor.getAlarmFlag())){
            return false;
        }

        if(!"running".equalsIgnoreCase(stockMonitor.getStatus())){
            return false;
        }

        if(stockMonitor.getStockName().indexOf("tt")>=0
                || stockMonitor.getStockName().indexOf("TT")>=0
                || stockMonitor.getStockName().indexOf("测试")>=0){
            return false;
        }

        String alarmCache = redisCache.getCacheObject(STOCK_MONITOR_AlARM_KEY + stockMonitor.getId());
        if(alarmCache!=null){
            return false;
        }

        long lnLeftCount = Long.parseLong(stockMonitor.getTotalCount()) - Long.parseLong(stockMonitor.getGrantCount());
        if(lnLeftCount<= Long.parseLong(stockMonitor.getAlarmCount())){
            return true;
        }

        DateTime endTime = DateUtil.parse(stockMonitor.getEndTime(),"yyyy-MM-dd HH:mm:ss");
        DateTime newEndTime = DateUtil.offsetDay(new Date(),stockMonitor.getExpireDays());

        if(newEndTime.isAfter(endTime)){
            return true;
        }

        return false;
    }

    //从微信后台加载所有列表
    public void loadMchCouponList(){
        int nHours = Integer.parseInt(DateUtil.format(new Date(),"HH"));
        if(nHours<8 || nHours>21){
            return;
        }

        try {
            List<TStockMch> stockMchList = stockMonitorMapper.findStockMchList();
            for(TStockMch stockMch:stockMchList){
                loadMchFromWechat(stockMch);
                stockMonitorMapper.updateStockMchById(stockMch);
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    public void loadMchFromWechat(TStockMch stockMch){
        try{
            String startDate = "2021-01-01T00:00:00+08:00";
            String endDate = DateUtil.format(new Date(),"yyyy-MM-dd") +"T23:59:59+08:00";

            if(stockMch.getUpdateTime()!=null){
                startDate = DateUtil.format(stockMch.getUpdateTime(),"yyyy-MM-dd") +"T00:00:00+08:00";
            }

            int nPage = 0;
            int nRows = 8;

            while (true) {
                String postUrl = "/v3/marketing/favor/stocks?offset=" + nPage;
                postUrl = postUrl + "&limit=" + nRows + "&stock_creator_mchid=" + stockMch.getMchId();
                postUrl = postUrl + "&create_start_time=" + URLEncoder.encode(startDate,"utf-8");
                postUrl = postUrl + "&create_end_time=" + URLEncoder.encode(endDate,"utf-8");

                String result = "";
                if(STOCK_CREATOR_MCHID.equalsIgnoreCase(stockMch.getMchId())) {
                    result = payService66.getV3(payService66.getPayBaseUrl() + postUrl);
                } else if(STOCK_CREATOR_MCHID_BIAO.equalsIgnoreCase(stockMch.getMchId())) {
                    result = payServiceBiao.getV3(payServiceBiao.getPayBaseUrl() + postUrl);
                } else {
                    //URI url = new URI(this.payService.getPayBaseUrl() + postUrl);
                    result = this.payService.getV3(this.payService.getPayBaseUrl() + postUrl);
                }

                JSONObject jsonObject = JSON.parseObject(result);
                Integer totalCount = jsonObject.getInteger("total_count");
                JSONArray jsonArray = jsonObject.getJSONArray("data");

                for(int i=0;i<jsonArray.size();i++){
                    TStockMonitor stockMonitorModel = new TStockMonitor();
                    JSONObject jsonDataObject = jsonArray.getJSONObject(i);
                    stockMonitorModel.setId(jsonDataObject.getString("stock_id"));
                    stockMonitorModel.setStockName(jsonDataObject.getString("stock_name"));
                    stockMonitorModel.setStockType(jsonDataObject.getString("stock_type"));
                    stockMonitorModel.setMchId(stockMch.getMchId());
                    stockMonitorModel.setMchName(stockMch.getMchName());

                    String beginTime = DateUtils.formatDateTime(DateUtils.dealDateFormat(jsonDataObject.getString("available_begin_time")));
                    String endTime = DateUtils.formatDateTime(DateUtils.dealDateFormat(jsonDataObject.getString("available_end_time")));

                    stockMonitorModel.setCreateTime(DateUtils.dealDateFormat(jsonDataObject.getString("create_time")));
                    stockMonitorModel.setBeginTime(beginTime);
                    stockMonitorModel.setEndTime(endTime);
                    stockMonitorModel.setStatus(jsonDataObject.getString("status"));
                    stockMonitorModel.setRemarks(jsonDataObject.getString("description"));

                    stockMonitorModel.setGrantCount(jsonDataObject.getString("distributed_coupons"));

                    String startTime = jsonDataObject.getString("start_time");
                    String stopTime = jsonDataObject.getString("stop_time");

                    if(StringUtils.isNotEmpty(startTime)){
                        stockMonitorModel.setActiveTime(DateUtils.formatDateTime(DateUtils.dealDateFormat(startTime)));
                    }
                    if(StringUtils.isNotEmpty(stopTime)){
                        stockMonitorModel.setStopTime(DateUtils.formatDateTime(DateUtils.dealDateFormat(stopTime)));
                    }

                    if(jsonDataObject.containsKey("stock_use_rule")){
                        JSONObject jsonStockUseRule = jsonDataObject.getJSONObject("stock_use_rule");
                        //发放总上限
                        stockMonitorModel.setTotalCount(jsonStockUseRule.getString("max_coupons"));
                        stockMonitorModel.setMaxAmount(jsonStockUseRule.getString("max_amount"));
                        stockMonitorModel.setAlarmCount(String.valueOf(Math.round(Long.parseLong(stockMonitorModel.getTotalCount()) * 0.2)));

                        stockMonitorModel.setMaxAmountByDay(jsonStockUseRule.getString("max_amount_by_day"));
                        //单个用户可领个数
                        stockMonitorModel.setMaxCouponsPerUser(jsonStockUseRule.getString("max_coupons_per_user"));

                        if(StringUtils.isNotEmpty(jsonStockUseRule.getString("coupon_type"))) {
                            stockMonitorModel.setCouponType(jsonStockUseRule.getString("coupon_type"));
                        }

                        JSONObject jsonFixedNormalCoupon = jsonStockUseRule.getJSONObject("fixed_normal_coupon");
                        if(jsonFixedNormalCoupon!=null){
                            stockMonitorModel.setCouponAmount(jsonFixedNormalCoupon.getString("coupon_amount"));
                            stockMonitorModel.setTransactionMnimum(jsonFixedNormalCoupon.getString("transaction_minimum"));
                        }
                    }

                    if(jsonDataObject.containsKey("cut_to_message")){
                        JSONObject jsonCutToMessage = jsonDataObject.getJSONObject("cut_to_message");
                        stockMonitorModel.setSinglePriceMax(jsonCutToMessage.getString("single_price_max"));
                        stockMonitorModel.setCutToPrice(jsonCutToMessage.getString("cut_to_price"));
                    }

                    String stockName = stockMonitorModel.getStockName();
                    String stockType = stockMonitorModel.getStockType();

                    if(stockName.indexOf("tt")>=0
                            || stockName.indexOf("TT")>=0
                            || stockName.indexOf("测试")>=0
                            || stockType.equalsIgnoreCase("DISCOUNT_CUT")) {
                        stockMonitorModel.setAlarmFlag("0");
                    } else {
                        stockMonitorModel.setAlarmFlag("1");
                    }

                    if(stockMonitorMapper.selectById(stockMonitorModel.getId())!=null){
                        stockMonitorMapper.updateStockMonitorById(stockMonitorModel);
                    } else {
                        logger.info(JSON.toJSONString(stockMonitorModel));
                        stockMonitorMapper.addStockMonitor(stockMonitorModel);
                    }
                }
                nPage  = nPage + 1;
                if((nRows * nPage) >= totalCount){
                    break;
                }
            }

        } catch (WxPayException wxPayException){
            if(!"批次不存在".equalsIgnoreCase(wxPayException.getCustomErrorMsg())){
                wxPayException.printStackTrace();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    private boolean canAllow() {
        Long stockMonitorTime = (Long)redisCache.getCacheObject(STOCK_MONITOR_KEY);

        if(stockMonitorTime!=null){
            lastAlarmTime = stockMonitorTime.longValue();
        }

        long now = System.currentTimeMillis();
        if (now - lastAlarmTime >= INTERVAL) {
            lastAlarmTime = now;
            redisCache.setCacheObject(STOCK_MONITOR_KEY,lastAlarmTime);
            return true;
        } else {
            return false;
        }
    }

}
